%% Code description
% This code simulates counterfactual rate adjustment regulations when
% lapses are endogenous. 
% Figure A.3 is generated.

%% Housekeeping
clear;

% root directory: change accordingly
root_dir = '...';

% add the files in demand & supply estimation folder
addpath(fullfile(root_dir, 'matlab/demand_estimation_AK'));
addpath(fullfile(root_dir, 'matlab/supply_estimation'));

%% Load data, demand & supply estimates, and other parameters of the model
load(fullfile(root_dir, 'matlab/supply_estimation/supply_estimates.mat'));

disp(' ')
disp('***************************************************')
disp('Counterfactual with endogenous lapses starts')
disp('***************************************************')
disp(['alpha= ', num2str(alpha)])

% compute observed insured rate at the market level: mean is 19.65%
D_enroll_st = zeros(N.st,1);
for mm=1:N.st
    ind=find(D.mkt==mm);
    D_enroll_st(mm) = sum(D.s1(ind));
end

% rename some variables
Delta_xi_all = D_unmerge.Delta_xi;
cost1_e_all  = cost1_e; % min loss ratio reg cost coefficient, NNx 1
cost2_1_all  = cost2_1; % rate stability reg cost coefficient, NN x KM
cost2_0      = cost2_0_mat; % rate stability reg fixed cost, NN x KM

clear Delta_xi cost1_e cost2_1 pr_stay

temp = load(fullfile(root_dir, 'matlab/demand_estimation_AK/demand_estimates.mat'));
use_log_n = temp.use_log_n;
clear temp

major= D_unmerge.major;
pr_s = D_unmerge.pr_s;
Ecost_rs = sum(pr_s.*cost_rs,2);
Ecost_rs_pe = Ecost_rs./D_unmerge.s1; % per-enrollee cost

% baseline estimates for rate adjustment cost coeff
Ecost2_1_base = sum(cost2_1_all.*D_unmerge.pr_s,2);

% needed to unmerge prices to provide as initial values
N_st = N.st;
D_major = D.major;
D_nF = D.n_insurers(D_major==0); % N_st x 1, contains # of fringes in a given mkt
arg_share=0;

% in the same order as D, store expanded agg states and rate increases
for jj=1:N.ist
    id_jj = D.id_ist(jj);
    ind = find(D_unmerge.id_ist==id_jj);
    ind = ind(1);
    D.pr_s_m(jj,:) = D_unmerge.pr_s(ind,:);
    D.p2_m(jj,:) = D_unmerge.p2(ind,:);
end

% needed to store in arrays with nrows=N.ist, preserving initial ordering in D
id_ist_old = D.id_ist;

% supply data with expanded agg states + unmerged fringes
D_input = D_unmerge;

% cost scales: to vary either fixed cost or variable cost 
scale_vec = [0.5; 0.7; 0.9;  1; 1.3; 1.7; 2];

%% lapse+edit: calibrate lapse_u, additive (dis)utility consumer gets from lapsing contract in t=2
ff = @(lapse_u_input)calibrate_lapse_u(lapse_u_input, D_input, N,...
    alpha, ...
    Delta_xi_all,...
    K, pr_y, N_y, resource_y1, resource_y2, y_medi, x_fc, pr_fc, ...
    rho, crra, sigma_c1, beta_c,  T1, B1_c, B2_c, delta, ...
    myopic, id_ist_old);

options = optimset('Display', 'iter',...
    'MaxFunEvals', 2000,...
    'MaxIter', 1000);

disp(' ')
disp('***************************************************')
disp('Estimation of lapse utility starts...')
disp('***************************************************')
lapse_u0 = -3;
[lapse_u_est, fval, exitflag, output] = fminsearch(ff, lapse_u0, options);
disp(' ')
disp(['Estimate of lapse_u = ', num2str(lapse_u_est)])

%% CF rate adjustment cost under baseline Medicaid
% Figure A.3 of Online Appendix generated. 
medi_cf=0; % baseline Medicaid
lapse_u = lapse_u_est;
[ssolve_market_all, ssolve_market, nnon_converge_all, nnon_converge]...
    = cf_rate_adjustmet_cost_lapse(lapse_u, medi_cf, scale_vec, cost2_0, cost2_1_all, D_input, D, N,...
    D_major, arg_share, D_nF, N_st,...
    D_enroll_st, ...
    alpha, ...
    Delta_xi_all, cost1_e_all, mu_f_all, sigma_f_all,...
    K, pr_y, N_y, resource_y1, resource_y2, y_medi, x_fc, pr_fc, ...
    rho, crra, sigma_c1, beta_c, beta_f, T1, B1_c, B2_c, B1_f, B2_f, delta, ...
    lr_target, N_f, entry_exitflag_vec, id_ist_old, myopic, Er, cost_weight, use_cost_weight,...
    root_dir);

save('cf_results_lapse.mat')










